#ifndef _BPT_ACSVR_H_
#define _BPT_ACSVR_H_

#include "z_server.h"
#include "z_util.h"
#include "ac_framework.h"
#include "z_lrm.h"
#include "z_persudo.h"
#include "z_guomi_persudo.h"
#include "print_guomi_persudo.h"
#include "z_gtpcvt.h"
#include "z_protocol_gsmeg.h"
#include "z_protocol.h"
#include "flow_ctrl.h"
#include "comhandler.h"
#include "guomi_trader.h"
#include "guomi_server.h"
#include "convert_handler.h"
#include "acsvr_share.h"
#include "bpt_cmd.h"
#include "nty_flow_send.h"
#include "flow_seq_manager.h"

#include "gsmeg_link_map.h"

/*  
#define _CHECK_VAL_TRUE_RET_LOG_DEBUG(stmt, ret, fmt, ...) do { \
     if( (stmt)){\
         DEBUG_PRINT(fmt, ##__VA_ARGS__);\
         return ret;       \
    } \
} while (0);  


#define _CHECK_VAL_TRUE_RET(stmt, ret, fmt, ...) do { \
     if( (stmt)){\
         ERROR_PRINT(fmt, ##__VA_ARGS__);\
         return ret;       \
    } \
} while (0);  

#define _CHECK_VAL_TRUE_LOG_GOON(stmt, fmt, ...) { \
     if( (stmt)){\
         ERROR_PRINT(fmt, ##__VA_ARGS__);\
         continue;\
    } \
};  */

#define ALLOC_GSMEG(gtp,len) do{\
    gsmeg = (z_gsmeg_t *)calloc(1,len+sizeof(z_gsmeg_t));\
    gsmeg->size_ = len + sizeof(z_gsmeg_t);\
}while(0);
#define BPT_CHECK_SEAT_ID(cmd_name,req_hash,seat_id)\
        case cmd_name:\
            seat_id = zH_strfind_string(req_hash,GTP_SEATID_TAG);\
            if(NULL == seat_id){\
                INFO_PRINT("Fail: lose  seat_id ") ;\
                return -1;\
            }\
            if(0x00==strcmp( link_info->seat_id_,string2str(seat_id))){  \
                INFO_PRINT("Suc:seat_id[%s] vs login_seat_id[%s]",string2str(seat_id),link_info->seat_id_) ;\
                return 0; \
            }else{ \
                INFO_PRINT("Fail:seat_id[%s] vs login_seat_id[%s]",string2str(seat_id),link_info->seat_id_) ;\
                return 1; \
           }

#define BPT_CHECK_SEAT_AND_TRADER_ID(cmd_name,req_hash,seat_id,trader_id)\
        case cmd_name:\
            trader_id = zH_strfind_string(req_hash,GTP_TRADERID_TAG);\
            seat_id = zH_strfind_string(req_hash,GTP_SEATID_TAG);\
            if((NULL == trader_id) ||(NULL == seat_id)){\
                INFO_PRINT("Fail: lose trader_id %d or seat_id %d",trader_id,seat_id) ;\
                return -1;\
            }\
            if(0x00==strcmp( link_info->seat_id_,string2str(seat_id))&&  \
                0x00==strcmp( link_info->trader_id_,string2str(trader_id))){ \
                INFO_PRINT("Suc:seat_id[%s] vs login_seat_id[%s]  trader_id[%s] vs login_trader_id[%s]",string2str(seat_id),link_info->seat_id_,string2str(trader_id),link_info->trader_id_) ;\
                return 0; \
            }else{ \
                INFO_PRINT("Fail:seat_id[%s] vs login_seat_id[%s]  trader_id[%s] vs login_trader_id[%s]",string2str(seat_id),link_info->seat_id_,string2str(trader_id),link_info->trader_id_) ;\
                return 1; \
           }

#define AC_HEAD_BUFF_LENGTH sizeof(z_acsvr_head_t)
#define RSPCODE_LENGTH 40 
#define BPTSVR_ERRCODE_HEAD 4

#define TO_GEMS 1
#define TO_GSMEG 2

#define MSG_TYPE_RESPONSE   1
#define MSG_TYPE_BROADCAST  2

#define IP_LEN 16

#define GTP_TO_HASH_FAILED 1800
#define INVAILD_CONVERT_TYPE 1801
#define MSG_TYPE_NOT_FOUND 1802
#define NOT_FIND_VERSION 1803
#define NOT_FIND_USERID 1804
#define NOT_FIND_TRADERID 1805
#define NOT_FIND_MANDATORY_VALUE 1806

#define CONVERT_RSPCODE_FAILED 1807
#define CONVERT_GSMEG_TO_GTP_FAILED 1808
#define INSERT_STR_TO_LOGOUT 1809

#define ENC_MODE_HARD '0'
#define OPTYPE_ADD '1'           
#define OPTYPE_MOD '2'       
#define OPTYPE_DEL '0'

#define DEV_LOGIN_EVENT  "3004"
#define DEV_LOGOUT_EVENT "3005"

#define GTP_USERID_TAG "G20"
#define GTP_TRADERID_TAG "M60"
#define GTP_SEATID_TAG "M20"
#define GTP_USERSYSTEM_TAG "X25"
#define GTP_VERSION_TAG "X55"

#define GSMEG_ACSVR_HEAD_TAG "acsvr_head"
#define GSMEG_DEV_ID_TAG "devId"
#define GSMEG_RSP_CODE_TAG "rspCode"
#define GSMEG_RSP_MSG_TAG "rspMsg"
#define GSMEG_TRADER_ID_TAG "traderID"
#define GSMEG_SEAT_ID_TAG "seatID"
#define GSMEG_USER_ID_TAG "userID"
#define GSMEG_USER_SYSTEM_TAG "userSystem"

#define GSMEG_SUCCESS_RSP_CODE "RSP000000"
#define ERR_CFG_RSP_CODE "rsp_code"
#define ERR_CFG_RSP_MSG "rsp_msg"

typedef struct bpt_acsvr_ctx {
	z_hash_t *link_id_map_;  //link_info_map [key:ll-channel_id(link_id) ,value:struct-z_link_t]
	z_hash_t *user_id_map_;	 //user_info_map [key:str-user_id,value:ll-channel_id]
	z_hash_t *trader_id_map_; //trader_info_map [key:str-trader_id,value:ll-channel_id]
	z_hash_t *seat_id_map_;   //seat_info_map [key;str-seat_id,value:z_hash_t-channel_id_hash{key:ll-channel_id,value:str-trader_id}]
	//z_hash_t *session_map_;  //unused since may be two same trader in session_map 
	z_hash_t *version_cfg_;  
    z_hash_t *trader_right_;
	z_hash_t *errcode_;		
    gsmeg_link_map_t *gsmeg_link_hashmap_;  
    //z_hash_t *gsmeg_link_hashmap_;  
    z_hash_t *gsmeg_link_cfg_;
	cvt_handle_t *gtp_cvt_handle_;
    bpt_convert_handle_t *cvt_handle_;
	long long trader_port_;
	long long user_port_;
	long long user_limit_;
	long long user_cnt_;
	long long dev_id_;
    char dev_name_[16];
	long long ready_flag_;     
	time_t cur_time_;	
	char trade_date_[16];
	char gtp_version_[8];
	z_gtp_t *gtp_pub_;
    ac_flow_ctrl_t *flow_ctrl_;
    api_safe_server_t  *safe_server_handle_;
	guomi_safe_ctx_t *guomi_safe_ctx_;
    enc_mode_manager_t *enc_mode_manager_;
    enc_pub_key_manager_t *enc_pub_key_manager_;
    sign_pub_key_manager_t *sign_pub_key_manager_;
    api_safe_server_link_t *safe_server_link_;
    int is_first_logined_;
    flow_seq_manager_t *flow_seq_manager_;
    z_hash_t *gsmeg_print_blacklist_;
} bpt_acsvr_ctx_t;

void add_devId_in_hash(z_hash_t *hash_req,long long  dev_id);
void add_acsvr_head_in_req_hash(z_hash_t *hash_req,z_acsvr_head_t *req_head);
int check_gtp2gsmeg_convert_process(z_hash_t *hash_req,z_hash_t *gtp2json_map,int *rsp_code);
int handle_gtp_input(z_gtp_t *gtp,int channel_id,int port);
int user_msg_handler(z_hash_t *hash_req, z_gtp_head_t *gtp_head, long long cmd_no, int channel);
void send_com_err_gtp_rsp_to_user(z_gtp_head_t *gtp_head,z_gtp_t *gtp,int err_code,int channel_id,z_hash_t *err_code_cfg);
int trader_msg_handler(z_head_t *gems_req,z_hash_t *hash_req,long long cmd_no,z_link_t *link_info,z_gtp_head_t *gtp_head);
char *get_msgtype_from_hash_req(z_hash_t *hash_req);
long long get_cmd_from_hash_req(z_hash_t *hash_req,bpt_convert_handle_t *cvt_handle);
int prepare_and_send_gsmeg_req(z_hash_t * src_hash_req,z_gtp_head_t *gtp_head,bpt_convert_handle_t *cvt_handle,z_hash_t *gsmeg_link_hashmap,int channel);

int handle_gsmeg_input(z_gsmeg_t *gsmeg_msg,int channel);
int handle_biz_gsmeg(z_gsmeg_t *gsmeg_msg,z_hash_t *gsmeg_hash);
int gsmeg_handler(z_gsmeg_t *gsmeg_msg);

int convert_handler_gsmeg2gtp(z_hash_t *gsmeg_hash,long long cmd,int con_len, z_acsvr_head_t *ac_head, z_gtp_t *gtp,bpt_convert_handle_t *bpt_cvt_handler,int gsem_msg_type);
int conver_handler_rspcode(z_hash_t *gsmeg_hash,z_hash_t *errcode_map);


//logout_handler.c
void send_trader_logout_req(z_link_t *link_info);
void send_user_logout_req(z_link_t *link_info);
void send_logout_req_and_clean_info(long long channel_id);

//map_info_manage.c
void insert_trader_map_info(z_hash_t *seat_id_map,z_hash_t *trader_id_map,char *seat_id,char *trader_id,int channel_id);
void clean_trader_map_info(z_hash_t *seat_id_map,z_hash_t *trader_id_map,char *seat_id,char *trader_id,int channel_id);
void update_trader_map_info(z_hash_t *seat_id_map,z_hash_t *trader_id_map,char *old_seat_id,char *old_trader_id,char *new_seat_id,char *new_trader_id,int old_channel_id,int new_channel_id);
void insert_user_map_info(z_hash_t *user_id_map,char *user_id,int channel_id);
void clean_user_map_info(z_hash_t *user_id_map,char *user_id);
void update_user_map_info(z_hash_t *user_id_map,char *old_user_id,char *new_user_id,int channel_id);


//check.c
long long trader_login_check(z_hash_t* req,z_link_t *link_info);
long long user_login_check(z_hash_t* hash_req);
long long common_check(z_hash_t *hash_req,z_link_t *link_info,bpt_convert_handle_t *cvt_handle,long long op_type);
int check_trade_date(char* trade_date_correct,char* trade_date_req);

#endif
